from flask import Flask
import pymysql
from apps.book import bp as book_bp
from apps.course import bp as course_bp
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

app=Flask(__name__)

#连接数据库
#地址
HOSTNAME='127.0.0.1'
PORT=3306
DATABASE='mql'
USERNAME='root'
PASSWORD='123456'
DB_URI='mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)

app.config['SQLALCHEMY_DATABASE_URI']=DB_URI

#用于跟踪和修改的
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=True

#验证
db=SQLAlchemy(app)


class User(db.Model):
    __tablename__="User"
    id=db.Column(db.Integer,primary_key=True,autoincrement=True)
    username=db.Column(db.String(200),nullable=False)


#存储用户不常用的信息
#与User是一对一的关系
class UserExtension(db.Model):
    __tablename__="UserExtension"
    id=db.Column(db.Integer,primary_key=True,autoincrement=True)
    school=db.Column(db.String(200),nullable=False)
    user_id=db.Column(db.Integer,db.ForeignKey("User.id"))
    #db.backref
    #1.在反向引用的时候，若需要传递一些其他的参数，那么就需要用到这个函数
    #否则不需要，只要在relationship的backref参数上，设置反向引用的名称就可以了
    #2.userlist=False,代表反向引用的时候，不是一个列表，而是一个对象
    user=db.relationship("User",backref=db.backref("extension",uselist=False))
    
    
#测试一对一

@app.route('/oto')

def one_to_one():
    #由于上面每次写完都把删掉，所以直接创建
#    user=User.query.filter_by(id=1).first()
    user=User(username='mql')
    extension=UserExtension(school='清华大学')
    user.extension=extension
    db.session.add(user)
    db.session.commit()
    return 'one_to_one数据操作成功'





#测试,一对多
@app.route("/otm")
def one_to_many():
    article=Article(title='111',content='xxx')
    user=User(username='mql')
    article.author=user
    db.session.add(article)
    db.session.commit()
    return "one_to_many数据操作成功"


#ORM映射与增删查询操作（实际上就是创建一个类
#括号里面为上面的db.model
class Article(db.Model):
    #定义表的名字
    __tablename__='ab'
    #定义第一个列名,类型为整型，主键，自动增长
    id=db.Column(db.Integer,primary_key=True,autoincrement=True)
    #定义第二列,类型为字符串，且长度为200
    title=db.Column(db.String(200),nullable=False)
    #第三列数据类型为文本
    content=db.Column(db.Text,nullable=False)
    
    #添加作者id
    #外键，
    #外键的数据类型一定要看，所引用的字段类型
    #2.db.ForeignKey("表名.字段名")
#    3.外键属于数据框层面，不推荐直接在ORM中使用
    author_id=db.Column(db.Integer,db.ForeignKey("User.id"))

    #relationship
    #User为上面定义的模型，必须要和模型的名字保持一致
    #backref---反向引用，代表对方访问我的时候的字段名称articles加s为复数，
    author=db.relationship("User",backref="articles")

'''
使用migrate进行迁移，需在终端执行以下命令：
flask db init---初始化
flask db migrate -m +"自定义脚本名称"-----生成迁移脚本
flask db upgrade  ---最终命令
'''

#使用下面两句进行映射表不太方面，一般使用flask-mirage,放在这主要用来迁移表
migrate=Migrate(app,db)#对象

#暂时还没有讲到ORM迁移数据库的版本管理，所以先删除所有表，再创建
#db.drop_all()
##将ORM模型转为数据库里面的表，执行下面的命令
#    
#db.create_all()#会自动在数据库当中创建一个表

##t添加数据
@app.route('/list')

def article_view():
    #1.添加数据
    #2.一般使用的语句是 insert table aritcle values(XX)
#    aticle=Article(title="钢铁是怎么炼成的",content="XXX")
#    #添加进去
#    db.session.add(aticle)
#    #提交
#    db.session.commit()
#    
    #查找数据
#    asbh=Article.query.filter_by(id=1)[0]
#    print(asbh.title)
    
    #修改数据
#    asbh=Article.query.filter_by(id=1)[0]
#    asbh.content='yyy'
#    db.session.commit()
    
    #删除数据---delete
    asbh=Article.query.filter_by(id=1).delete()
    db.session.commit()
    
    return '操作成功'


#验证---运行后出现1即为连接成功
@app.route('/')
def mql():
    engine=db.get_engine()#引擎
    
    with engine.connect() as cnn:
        result=cnn.execute('select 1')
        print(result.fetchone())
    return '图书列表'




#配置蓝图
#app.register_blueprint(book_bp)
#app.register_blueprint(course_bp)

if __name__=='__main__':
    app.run(debug=True)